import { generateUUID } from '../../utils'
import { addReadyProduct } from '../core/ReadyProducts'
import { schedule } from '../core/Scheduler'
import { currentTime } from '../core/SimulationClock'
import { messageTransfer } from '../messaging/MessageTransfer'
import BaseStation from './BaseStation'
import Product from './Product'

class Generator extends BaseStation {
  productCounter = 0
  interval: number | string
  totalCount: number
  selfCirculation: boolean
  productWidth: number
  productHeight: number

  constructor(
    id: string,
    name: string,
    x: number,
    y: number,
    width = 100,
    height = 100,
    interval: number | string,
    totalCount: number,
    selfCirculation = true,
    productWidth: number = 20,
    productHeight: number = 20
  ) {
    super(id, name, x, y, width, height)
    this.interval = interval
    this.totalCount = totalCount
    this.selfCirculation = selfCirculation
    this.productWidth = productWidth
    this.productHeight = productHeight
  }

  start(): void {
    this.tryDispatchCurrentProduct(true)
  }

  scheduleNext(): void {
    if (this.totalCount !== -1 && this.productCounter >= this.totalCount) return
    let time = 0
    if (typeof this.interval === 'string') {
      time = new Function(this.interval)()
    } else {
      time = this.interval
    }
    schedule(time, () => this.tryDispatchCurrentProduct(true), `${this.id} 生成产品`)
  }

  canReceiveProduct(): boolean {
    return false
  }
  onProductReceived(): void {
    throw new Error('Generator cannot receive ready product')
  }

  tryDispatchCurrentProduct(outside = false): boolean {
    const intervalAllocation = (): void => {
      const product = new Product(generateUUID(), this.productWidth, this.productHeight)

      const availableStation = this.nextStations.find((s) => s.canReceiveProduct(this.id, product))
      if (availableStation === undefined) {
        console.log(`[${currentTime}] ⛔ ${this.name} 下游无空闲设备`)
        this.scheduleNext()
        //如果下游不接收，则删除本产品
        return
      }

      console.log(`[${currentTime}] 🚀 ${this.name} 产生 ${product.id}`)
      product.setFrom(this.id)
      messageTransfer('product', 'generate', { targetId: this.id, productId: product.id })
      // messageTransfer('product', 'startProcessing', { targetId: this.id, productId: product.id })

      //把产品交给就绪产品队列中
      addReadyProduct(product)
      availableStation.receiveReadyProduct(product.id)
      this.productCounter++
      if (this.totalCount !== -1) {
        messageTransfer('style', null, {
          targetId: this.id,
          style: {
            quantity: this.totalCount - this.productCounter
          }
        })
      }

      this.scheduleNext()
    }
    if (outside) {
      if (this.selfCirculation) {
        intervalAllocation()
        return false
      } else {
        console.log('正在开发')
        return false
      }
    } else {
      if (this.selfCirculation) {
        console.log('直接跳过')
        return false
      } else {
        console.log('正在开发')
        return false
      }
    }
  }
}

export default Generator
